package com.micro.service.auth.server.login.validateCode;

import com.micro.service.auth.server.config.handler.LoginFailureHandler;
import com.micro.service.auth.server.config.properties.SecurityProperties;
import com.micro.service.auth.server.exception.ValidateCodeException;
import org.apache.commons.lang.StringUtils;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author lvxiucai
 * @description  图片短信验证码过滤器
 * @date 2019/7/20
 */
@Component
public class ValidateCodeFilter extends OncePerRequestFilter {


    private LoginFailureHandler loginFailureHandler;

    private SessionStrategy sessionStrategy ;

    private SecurityProperties securityProperties;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        if(StringUtils.equals("/authentication/form",request.getRequestURI())
                &&StringUtils.equalsIgnoreCase(request.getMethod(),"post" )
                && StringUtils.equals("true",securityProperties.getIsOpenValidateCode())){//只有登录并且为post请求，开启验证码才会校验

            try{
                validate(new ServletWebRequest(request));
            }catch (ValidateCodeException e){
                loginFailureHandler.onAuthenticationFailure(request,httpServletResponse,e);
                return;
            }

        }
        filterChain.doFilter(request,httpServletResponse);
    }

    private void validate(ServletWebRequest request) throws ServletRequestBindingException {
        String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(),"code");
        String codeType = ServletRequestUtils.getStringParameter(request.getRequest(),"codeType");


        if(codeType == null){
            throw new ValidateCodeException("验证码类型不能为空");
        }
        if(StringUtils.isBlank(codeInRequest)){
            throw new ValidateCodeException("验证码的值不能为空");
        }

        if(codeType.equalsIgnoreCase("IMAGE")){
            ImageCode codeInSession = (ImageCode)sessionStrategy.getAttribute(request,ValidateCodeController.SESSION_KEY_PREFIX+codeType);

            if(codeInSession == null){
                throw new ValidateCodeException("验证码已过期");
            }

            if(!StringUtils.equals(codeInSession.getCode(),codeInRequest)){
                throw new ValidateCodeException("验证码不正确");
            }
            if(codeInSession.isExpired()){
                sessionStrategy.removeAttribute(request,ValidateCodeController.SESSION_KEY_PREFIX+codeType);
                throw new ValidateCodeException("验证码已过期");
            }
            sessionStrategy.removeAttribute(request,ValidateCodeController.SESSION_KEY_PREFIX+codeType);
        }

    }

    public LoginFailureHandler getLoginFailureHandler() {
        return loginFailureHandler;
    }

    public void setLoginFailureHandler(LoginFailureHandler loginFailureHandler) {
        this.loginFailureHandler = loginFailureHandler;
    }

    public SessionStrategy getSessionStrategy() {
        return sessionStrategy;
    }

    public void setSessionStrategy(SessionStrategy sessionStrategy) {
        this.sessionStrategy = sessionStrategy;
    }

    public SecurityProperties getSecurityProperties() {
        return securityProperties;
    }

    public void setSecurityProperties(SecurityProperties securityProperties) {
        this.securityProperties = securityProperties;
    }


}
